﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text.RegularExpressions;
using System.Web;
using System.IO;

namespace MyUPSMonitor
{
    [global::System.Serializable]
    public class AgentException : Exception
    {
        public AgentException() { }
        public AgentException(string message) : base(message) { }
        public AgentException(string message, Exception inner) : base(message, inner) { }
        protected AgentException(
          System.Runtime.Serialization.SerializationInfo info,
          System.Runtime.Serialization.StreamingContext context)
            : base(info, context) { }
    }

    public class MyUPSAgent
    {

        public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }

        private static string getValue(string key, string myResponse)
        {
            Regex re = new Regex(key + "<\\/td>\\r?\\n?.*\\r\\n[^>]+>([^<]+)<", RegexOptions.IgnoreCase);
            Match reMatch = re.Match(myResponse);
            return reMatch.Groups[1].Value.Replace("&nbsp;", " ").Replace("&deg;", "°");
        }

        private static string getWebResponse(string myURLBase, string myUserName, string myPassword)
        {
            ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateServerCertificate);
            string myResponse;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(myURLBase + "/j_security_check");
            request.Method = "POST";
            
            string data2Send = "j_username=" + myUserName + "&j_password=" + System.Web.HttpUtility.UrlEncode(myPassword);
            request.ContentLength = UTF8Encoding.UTF8.GetByteCount(data2Send);
            request.ContentType = "application/x-www-form-urlencoded";
            Stream dataStream;
            try
            {
                dataStream = request.GetRequestStream();
            }
            catch
            {
                return "Error: Getting WEB response.";
            }
            StreamWriter datastreamwriter = new StreamWriter(dataStream);
            datastreamwriter.Write(data2Send);
            datastreamwriter.Close();
            dataStream.Close();
            WebResponse response = request.GetResponse();
            Stream respStream = response.GetResponseStream();
            StreamReader respReader = new StreamReader(respStream);
            string responseStr = respReader.ReadToEnd();
            respReader.Close();
            respStream.Close();
            response.Close();
            if (responseStr.IndexOf("That is not a valid username and password") > -1)
            {
                return "Error: Invalid Username or password";
            }
            else
            {
                if (responseStr.IndexOf("<title>PowerChute Business Edition</title>") < 1)
                {
                    return "Error: Unexpected answer.";
                }
                else
                {
                    Regex re = new Regex("frame\\ssrc\\=\\\"\\/original;([^\"]+)", RegexOptions.IgnoreCase);
                    Match rematch = re.Match(responseStr);
                    string myID = rematch.Groups[1].Value;
                    request = (HttpWebRequest)WebRequest.Create(myURLBase + "/original;" + myID);
                    request.Method = "GET";
                    response = request.GetResponse();
                    respStream = response.GetResponseStream();
                    respReader = new StreamReader(respStream);
                    responseStr = respReader.ReadToEnd();
                    respReader.Close();
                    respStream.Close();
                    response.Close();

                    request = (HttpWebRequest)WebRequest.Create(myURLBase + "/status;" + myID);
                    request.Method = "GET";
                    response = request.GetResponse();
                    respStream = response.GetResponseStream();
                    respReader = new StreamReader(respStream);
                    myResponse = respReader.ReadToEnd();
                    respReader.Close();
                    respStream.Close();
                    response.Close();
                    return myResponse;
                }
            }
        }

        public static int GetMinutesRemaining(string URLBase, string UserName, string Password)
        {
            string respHTML = getWebResponse(URLBase, UserName, Password);
            if (respHTML.Substring(0,6)=="Error:")
            {
                throw new AgentException(respHTML);
            }
            string minrem = getValue("Runtime Remaining", respHTML);
            int i;
            if (int.TryParse(minrem.Substring(0, minrem.IndexOf(" ")), out i))
            {
                return i;
            }
            else
            {
                throw new AgentException("Error: Unexpected result from WEB request!");
            }
        }
        public static bool IsOnBattery(string URLBase, string UserName, string Password)
        {
            string respHTML = getWebResponse(URLBase, UserName, Password);
            if (respHTML.Substring(0,6)=="Error:")
            {
                throw new AgentException(respHTML);
            }
            return (getValue("Device Status", respHTML).ToLower() == "on battery");
        }
        public static string GetStatus(string URLBase, string UserName, string Password)
        {
            string respHTML = getWebResponse(URLBase, UserName, Password);
            if (respHTML.Substring(0, 6) == "Error:")
            {
                throw new AgentException(respHTML);
            }
            return (getValue("Device Status", respHTML));
        }
    }
}
